package com.hwy.chart.coordinate

import android.graphics.*
import androidx.annotation.ColorInt

/**
 * =======================================
 * 作者: hewenyu
 * 日期: 2022/5/10 15:25
 * 说明: 坐标系网格线
 * =======================================
 */
open class CoordinateGridLine {

    companion object {
        /**
         * 每个方向上最少需要绘制的线条数量，小于这个数量则不绘制
         */
        private const val MIN_LINE_COUNT = 2
    }

    private val gridLinePaint by lazy {
        Paint().apply {
            isAntiAlias = true
            isDither = true
            style = Paint.Style.FILL_AND_STROKE
        }
    }

    /**
     * 网格线颜色
     */
    @ColorInt
    var lineColor = Color.GRAY

    /**
     * 网格线粗细
     */
    var lineWidth = 1F

    private var horizontalLineCount = MIN_LINE_COUNT

    private var verticalLineCount = MIN_LINE_COUNT

    /**
     * 是否绘制网格线
     * true: 绘制(默认)
     * false:不绘制网格线
     */
    var isGridLineEnable = true

    /**
     * 设置网格线数量
     * @param verticalLineCount 纵向网格线数量
     * @param horizontalLineCount 横向网格线数量
     */
    fun setLineCount(verticalLineCount: Int, horizontalLineCount: Int) {
        this.verticalLineCount = verticalLineCount
        this.horizontalLineCount = horizontalLineCount
    }

    /**
     * 设置线条模型
     *
     * @param intervals 虚线间隔，传入null表示不适用虚线
     * [intervals]数组index奇数位表示实线长度
     * [intervals]数组index偶数位表示虚线的长度
     * @param phase 线条起始位置偏移量
     */
    fun setDashPathEffect(intervals: FloatArray?, phase: Float = 0F) {
        intervals?.run {
            if (size < 2 || size % 2 != 0) {
                throw RuntimeException("DashPathEffect intervals must greater than 2 and even.")
            }
            gridLinePaint.setPathEffect(DashPathEffect(intervals, phase))
        }
    }

    /**
     * 绘制网格线
     */
    fun draw(canvas: Canvas, bounds: RectF) {
        if (!isGridLineEnable) {
            return
        }
        gridLinePaint.run {
            strokeWidth = lineWidth
            color = lineColor
        }
        if (lineWidth > 0) {
            // 线条粗细>0时才支持绘制
            drawHorizontalLines(canvas, bounds)
            drawVerticalLines(canvas, bounds)
        }
    }

    /**
     * 绘制纵向的线条
     */
    protected open fun drawVerticalLines(canvas: Canvas, bounds: RectF) {
        if (verticalLineCount < MIN_LINE_COUNT) {
            return
        }
        // 每条线之间的间距
        val spacing = (bounds.width() - lineWidth) / (verticalLineCount - 1)
        var startX = bounds.left + lineWidth / 2F
        for (index in 0 until verticalLineCount) {
            canvas.drawLine(startX, bounds.top, startX, bounds.bottom, gridLinePaint)
            startX += spacing
        }
    }

    /**
     * 绘制横向的线条
     */
    protected open fun drawHorizontalLines(canvas: Canvas, bounds: RectF) {
        if (horizontalLineCount < MIN_LINE_COUNT) {
            return
        }
        // 每条线之间的间距
        val spacing = (bounds.height() - lineWidth) / (horizontalLineCount - 1)
        var startY = bounds.top + lineWidth / 2F
        for (index in 0 until horizontalLineCount) {
            canvas.drawLine(bounds.left, startY, bounds.right, startY, gridLinePaint)
            startY += spacing
        }
    }

}